package com.flycms.web.front.rest;

import java.util.Date;
import java.util.List;
import java.util.Objects;

import javax.validation.Valid;

import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.flycms.constant.StatusConst;
import com.flycms.core.base.BaseController;
import com.flycms.core.entity.PagingParam;
import com.flycms.core.entity.RestDataVo;
import com.flycms.core.utils.web.utils.CommonUtils;
import com.flycms.module.comment.model.Collects;
import com.flycms.module.comment.model.FlyContentType;
import com.flycms.module.comment.service.CollectsService;
import com.flycms.module.qasystem.model.Answers;
import com.flycms.module.qasystem.model.Questions;
import com.flycms.module.qasystem.service.AnswersService;
import com.flycms.module.qasystem.service.QuestionsService;

/**
 * 问答系统相关类
 * <br/> /qa/..
 *
 * <br/>Copyright 2020
 * <br/>All rights reserved
 * @author 沁言訫語
 * @version 2020年2月18日
 * @Date 2020年2月18日
 */

@RestController
@RequestMapping("/qa")
public class QAController extends BaseController {

    private static final Logger logger = LogManager.getLogger(QAController.class);
    
    @Autowired
    protected QuestionsService questionService;
    
    @Autowired
    protected AnswersService answerService;
    
    @Autowired
    protected CollectsService collectsService;
    
    /**
     * 新建问题
     * <br/> status == 2 不发表； status == 4 发表待审核
     * <br/> pub是否发表，默认不发表
     * @param question
     * @param errors
     * @return
     */
    
    @PostMapping(value = {"/question/u/add/{pub}"})
    public RestDataVo addQuestion(@Valid @RequestBody Questions question,
            @PathVariable(value = "pub") Boolean pub,
            BindingResult errors) {
        RestDataVo rest = null;
        Long userId = getUserId();
        String validResult = CommonUtils.validParams(errors, logger);
        if (StringUtils.isNotEmpty(validResult)) {
            return RestDataVo.ERROR(validResult);
        }
        Questions quest = new Questions();
        quest.setTitle(question.getTitle());
        quest.setContent(keywordFilter.doFilter(question.getContent()));
        quest.setProposeUserId(userId);
        quest.setCreateTime(new Date());
        if (Objects.equals(pub, true)) {
            quest.setStatus(StatusConst.TO_AUDIT.value());
        } else {
            quest.setStatus(StatusConst.NOUSE.value());
        }
//        reply
        try {
            questionService.addQuestion(quest);
            rest = RestDataVo.OK(quest);
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("新建问题异常，" + e.getMessage());
        }
        return rest;
    }
    
    /**
     * 用户查看当前问题
     * @param status
     * @param title
     * @param paging
     * @return
     * @author 沁言訫語
     */
    
    @PostMapping(value = {"/question/list"})
    public RestDataVo getQuestionListForCustom(@RequestParam(value = "title", required = false) String title,
            @RequestBody(required = false) PagingParam paging) {
        paging = CommonUtils.validPageParam(paging);
        Long proposeUserId = getUserId();
        RestDataVo rest = null;
        try {
            List<Questions> questList = questionService.getQuestionListForCustom(proposeUserId, title, paging.getOffset(), paging.getRows());
            int count = questionService.getQuestionCountForCustom(title, StatusConst.OPEN.value());
            for (Questions q : questList) {
                if (proposeUserId != null) {
                    Collects c = collectsService.queryCollectedCollect(proposeUserId, q.getId(), FlyContentType.QUESTION);
                    q.setICollect(c == null ? 0 : 1);
                } else {
                    q.setICollect(0);
                }
            }
            
            rest = RestDataVo.PAGE(questList, paging.getPageIndex(), paging.getPageSize(), count);
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("获取问题列表异常");
        }
        return rest;
    }
    
    @PostMapping(value = {"/question/hot"})
    public RestDataVo getQuestionListHot() {
        PagingParam paging = new PagingParam(null, null, 5, 0, 5, 0);
//        Long proposeUserId = getUserId();
        RestDataVo rest = null;
        try {
            List<Questions> questList = questionService.getQuestionListHot(paging.getOffset(), paging.getRows());
            rest = RestDataVo.PAGE(questList, 0, 5, 5);
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("获取优质问题列表异常");
        }
        return rest;
    }
    
    /**
     * 发布自己保存的一个问题
     * @param id
     * @return
     * @author 沁言訫語
     */
    
    @PostMapping(value = {"/question/u/pub/{id}"})
    public RestDataVo pubQuestion(@PathVariable("id") Long id) {
        RestDataVo rest = null;
        Long userId = getUserId();
        Questions quest = null;
        try {
            quest = questionService.queryQuestionById(id);
            if (quest == null || !Objects.equals(quest.getStatus(), StatusConst.CLOSE.value())
                    || !Objects.equals(quest.getProposeUserId(), userId)) {
                return RestDataVo.ERROR("问题不存在或该问题已发表");
            }
        } catch (Exception e) {
            logger.error("", e);
            return RestDataVo.ERROR("发表问题异常");
        }
//        if (Objects.equals(pub, true)) {
//            quest.setStatus(StatusConst.TO_AUDIT.value());
//        } else {
//            quest.setStatus(StatusConst.CLOSE.value());
//        }
//        reply
        try {
            questionService.editQuestion(id, StatusConst.TO_AUDIT.value(), "", new Date(), userId);
            rest = RestDataVo.OK("发表成功");
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("新建问题异常，" + e.getMessage());
        }
        return rest;
    }
    
    /**
     * 个人中心查看问题列表
     * @param title
     * @param paging
     * @return
     * @author 沁言訫語
     */
    
    @PostMapping(value = {"/question/u/self/list", "/question/u/self/{userid}/list"})
    public RestDataVo getSelfQuestionList(@RequestParam(value = "title", required = false) String title,
            @PathVariable(value = "userid", required = false) Long userId,
            @RequestBody(required = false) PagingParam paging) {
        paging = CommonUtils.validPageParam(paging);
        Long proposeUserId = null;
        Integer status = null;
        if (userId == null) {
            proposeUserId = getUserId();
        } else {
            proposeUserId = userId;
//            status = StatusConst.OPEN.value();
        }
        RestDataVo rest = null;
        try {
            List<Questions> questList = questionService.getQuestionList(proposeUserId,
                    status, title, paging.getOrderBy(),
                    paging.getOrder(), paging.getOffset(), paging.getRows());
            int count = questionService.getQuestionCount(proposeUserId, title, status);
            rest = RestDataVo.PAGE(questList, paging.getPageIndex(), paging.getPageSize(), count);
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("获取问题列表异常");
        }
        return rest;
    }
    
    @GetMapping(value = {"/question/other/{userid}/list"})
    public RestDataVo getOtherQuestionList(@RequestParam(value = "title", required = false) String title,
            @PathVariable(value = "userid") Long userId,
            @RequestParam(value = "pageIndex", required = false) Integer pageIndex,
            @RequestParam(value = "pageSize", required = false) Integer pageSize) {
        PagingParam paging = CommonUtils.validParam(pageIndex, pageSize);
        Long proposeUserId = null;
        Integer status = null;
        if (userId == null) {
            return RestDataVo.ERROR("未传入用户ID");
        } else {
            proposeUserId = userId;
            status = StatusConst.OPEN.value();
        }
        RestDataVo rest = null;
        try {
            List<Questions> questList = questionService.getQuestionList(proposeUserId,
                    status, title, paging.getOrderBy(),
                    paging.getOrder(), paging.getOffset(), paging.getRows());
            int count = questionService.getQuestionCount(proposeUserId, title, status);
            rest = RestDataVo.PAGE(questList, paging.getPageIndex(), paging.getPageSize(), count);
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("获取问题列表异常");
        }
        return rest;
    }
    
    /**
     * 查询问题详情
     * @param id
     * @return
     * @author 沁言訫語
     */
    
    @PostMapping(value = {"/question/{id}"})
    public RestDataVo getQuestionDetail(@PathVariable(value = "id") Long id) {
        RestDataVo rest = null;
        Long userId = getUserId();
        try {
            Questions quest = questionService.queryQuestionById(id, userId);
            try {
                Collects col = collectsService.queryCollectedCollect(userId, id, FlyContentType.QUESTION);
                quest.setICollect(col != null ? 1 : 0);
            } catch (Exception e) {
                
            }
            if (quest != null) {
                rest = RestDataVo.OK(quest);
            } else {
                rest = RestDataVo.ERROR("为查询到id为{}的问题", id + "");
            }
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("获取问题异常");
        }
        return rest;
    }
    
    /**
     * 回答问题
     * @param answer
     * @param pub
     * @param errors
     * @return
     * @author 沁言訫語
     */
    
    @PostMapping(value = {"/answer/u/add/{pub}"})
    public RestDataVo addAnswer(@Valid @RequestBody Answers answer,
            @PathVariable(value = "pub") Boolean pub, BindingResult errors) {
        RestDataVo rest = null;
        Long userId = getUserId();;
        String validResult = CommonUtils.validParams(errors, logger);
        if (StringUtils.isNotEmpty(validResult)) {
            return RestDataVo.ERROR(validResult);
        }
        //查询回答的问题是否存在且处于打开状态（审核通过）
        try {
            Questions question = questionService.queryQuestionById(answer.getQuestionId());
            if (question == null || !Objects.equals(question.getStatus(), StatusConst.OPEN.value())) {
                rest = RestDataVo.ERROR("问题id:{0}不存在或已关闭", answer.getQuestionId());
                return rest;
            }
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("新增问题回答异常");
            return rest;
        }
        Answers ans = new Answers();
        ans.setContent(keywordFilter.doFilter(answer.getContent()));
        ans.setCreateTime(new Date());
        ans.setQuestionId(answer.getQuestionId());
        ans.setReplyUserId(userId);
        ans.setUpCount(0);
        ans.setDownCount(0);
        ans.setCollectCount(0);
        ans.setCommentCount(0);
        if (Objects.equals(pub, true)) {
            ans.setStatus(StatusConst.TO_AUDIT.value());
        } else {
            ans.setStatus(StatusConst.NOUSE.value());
        }
//        reply
        try {
            answerService.addAnswer(ans);
            rest = RestDataVo.OK(ans);
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("新增问题回答异常");
        }
        return rest;
    }
    
    /**
     * 发表自己保存的一个回答
     * @param id
     * @return
     * @author 沁言訫語
     */
    
    @PostMapping(value = {"/answer/u/pub/{id}"})
    public RestDataVo pubAnswer(@PathVariable("id") Long id) {
        RestDataVo rest = null;
        Long userId = getUserId();;
        //查询回答的问题是否存在且处于打开状态（审核通过）
        try {
            Answers answer = answerService.queryAnswerById(id, StatusConst.CLOSE.value());
            if (answer == null || !Objects.equals(answer.getStatus(), StatusConst.CLOSE.value())
                    || !Objects.equals(answer.getReplyUserId(), userId)) {
                rest = RestDataVo.ERROR("回答不存在或已发表");
                return rest;
            }
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("发表问题回答异常");
            return rest;
        }
        try {
            answerService.editAnswer(id, null, StatusConst.TO_AUDIT.value(), new Date(), userId);
            rest = RestDataVo.OK("回答发表成功");
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("回答发表异常");
        }
        return rest;
    }
    
    /**
     * 查询某个问题的回答列表
     * @param questionId
     * @param paging
     * @return
     * @author 沁言訫語
     */
    
    @PostMapping(value = {"/answer/{questionId}/list"})
    public RestDataVo getQuestionAnswerList(
            @PathVariable(value = "questionId", required = false) Long questionId,
            @RequestBody(required = false) PagingParam paging) {
        paging = CommonUtils.validPageParam(paging);
        Long proposeUserId = getUserId();;//自己的userID
        RestDataVo rest = null;
        try {
            List<Answers> questList = answerService.getQuestionAnswerList(proposeUserId, questionId,
                    StatusConst.OPEN.value(), paging.getOffset(), paging.getRows());
            int count = answerService.getQuestionAnswerCount(proposeUserId, questionId, StatusConst.OPEN.value());
            rest = RestDataVo.PAGE(questList, paging.getPageIndex(), paging.getPageSize(), count);
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("获取问题列表异常");
        }
        return rest;
    }
    
    /**
     * 查看某个问题的详情
     * @param id
     * @return
     * @author 沁言訫語
     */
    
    @PostMapping(value = {"/answer/{id}"})
    public RestDataVo getAnswerDetail(@PathVariable(value = "id") Long id) {
        RestDataVo rest = null;
//        Long proposeUserId = getUserId();;//自己的userID
        try {
            Answers ans = answerService.queryAnswerById(id, null);
            if (ans == null) {
                rest = RestDataVo.ERROR("不存在id为{0}的回答", id + "");
            } else {
                rest = RestDataVo.OK(ans);
            }
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("获取回答异常");
        }
        return rest;
    }
    
    @PostMapping(value = {"/answer/remove/{id}"})
    public RestDataVo removeAnswer(@PathVariable(value = "id") Long id) {
        RestDataVo rest = null;
        Long proposeUserId = getUserId();;//自己的userID
        try {
            Answers ans = answerService.queryAnswerById(id, null);
            if (ans == null) {
                rest = RestDataVo.ERROR("不存在id为{0}的回答", id + "");
            } else {
                answerService.removeAnswerById(id, proposeUserId);
                rest = RestDataVo.OK(ans);
            }
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("删除回答异常");
        }
        return rest;
    }
    
}
